﻿using System;
using System.Collections.Generic;
using System.Text;
using SharpMedia.MDX;
using System.Windows.Forms;
using System.Threading;
using System.Security.Permissions;
using Lizk.Utilities;
using System.IO;
using System.Reflection;
using SharpMedia.Pages;
using SharpMedia.Input;
using Lizk.SimpleHUD;
using SharpMedia.Properties;
using System.Diagnostics;
using WallpaperRandomizer;

namespace SharpMedia
{
    public class Program
    {
        static void Main(string[] args)
        {
            CheckForManagedDirectX();
            if (!NETFramework.DialogCheckForVersion(NETFramework.Version.Version3_0) || !NETFramework.DialogCheckForVersion(NETFramework.Version.Version3_5))
                return;
            if (SystemTools.ProcessAlreadyRunning())
                return;

            Application.EnableVisualStyles();
            
            SharpMedia.RootDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
            if (!Directory.Exists(SharpMedia.RootDirectory))
                Directory.CreateDirectory(SharpMedia.RootDirectory);


            FileIOPermission perm = new FileIOPermission(PermissionState.Unrestricted);
            perm.Demand();

           

            bool settingsLoaded = SharpMedia.LoadSettings(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "felizk"), "SharpMedia"));

            if (args.Length != 0 || !settingsLoaded)
            {
                // Start a new STA thread because [STAThread] WILL NOT WORK :~(
                SettingsForm f = new SettingsForm();
                ManualResetEvent mre = new ManualResetEvent(false);
                if(!settingsLoaded)
                    f.FormClosed += new FormClosedEventHandler(delegate { mre.Set(); });
                Thread t = new Thread(new ThreadStart(delegate {Application.Run(f); }));
                t.SetApartmentState(ApartmentState.STA);
                t.Start();
                if(!settingsLoaded) 
                {
                    mre.WaitOne();
                } else
                    return;
            }
            ThreadPool.SetMinThreads(5, 5);
            Thread.CurrentThread.Name = "Form Thread";

            MDXForm form = new MDXForm(new System.Drawing.Size((int)SharpMedia.Settings.WindowSize.Width, (int)SharpMedia.Settings.WindowSize.Height));
            form.Windowed = SharpMedia.Settings.WindowedMode;
            form.HandleVista();
            form.Text = "SharpMedia";
            form.Icon = Resources.screen;
            form.WindowsMessages += new MDXForm.WndProcHandler(delegate(ref System.Windows.Forms.Message m, ref bool call) { OverlayPage2.diskMonitor.PreFilterMessage(ref m); });

            SharpMedia.renderer = new MDXRenderer(form)
            {
                ImageRoot = Path.Combine(SharpMedia.RootDirectory, "images"),
                FontRootDir = Path.Combine(SharpMedia.RootDirectory, @"fonts"),
                GarbageCollectionInterval = new TimeSpan(0, 4, 30)
            };
            SharpMedia.Engine = form;
            
            form.Renderer = (MDXRenderer)SharpMedia.renderer;

            form.DoUpdate += new EventHandler(Form_DoUpdate);
            form.Render += new EventHandler(Form_Render);
            form.FormClosing += new FormClosingEventHandler(Form_FormClosing);
            form.Shown += new EventHandler(Form_Shown);
            form.MouseDown += new MouseEventHandler(Form_MouseDown);
            form.MouseUp += new MouseEventHandler(Form_MouseUp);

            // Input Class
            FormInputController formInput = new FormInputController(Path.Combine(SharpMedia.DataDirectory, "input.xml"), form);
            formInput.FireCommand += new EventHandler<CommandEventArgs>(SharpMedia.HandleInput);

            Application.Run(form);
        }

        static void Form_Shown(object sender, EventArgs e)
        {
            Util.RunAsync(SharpMedia.Init, Thread.CurrentThread);
        }

        static void Form_FormClosing(object sender, FormClosingEventArgs e)
        {
            SharpMedia.Closing();
        }

        static void Form_Render(object sender, EventArgs e)
        {
            SharpMedia.Render();
        }

        static void Form_DoUpdate(object sender, EventArgs e)
        {
            SharpMedia.Update();
        }

        static void Form_MouseUp(object sender, MouseEventArgs e)
        {
            HUDControl.MouseButtons button = HUDControl.MouseButtons.None;
            switch (e.Button)
            {
                case MouseButtons.Left:
                    button = HUDControl.MouseButtons.Left;
                    break;
                case MouseButtons.Middle:
                    button = HUDControl.MouseButtons.Middle;
                    break;
                case MouseButtons.None:
                    button = HUDControl.MouseButtons.None;
                    break;
                case MouseButtons.Right:
                    button = HUDControl.MouseButtons.Right;
                    break;
                default:
                    break;
            }
            SharpMedia.MouseUp(new Lizk.SimpleHUD.PointS(e.X, e.Y), button);
        }

        static void Form_MouseDown(object sender, MouseEventArgs e)
        {
            HUDControl.MouseButtons button = HUDControl.MouseButtons.None;
            switch (e.Button)
            {
                case MouseButtons.Left:
                    button = HUDControl.MouseButtons.Left;
                    break;
                case MouseButtons.Middle:
                    button = HUDControl.MouseButtons.Middle;
                    break;
                case MouseButtons.None:
                    button = HUDControl.MouseButtons.None;
                    break;
                case MouseButtons.Right:
                    button = HUDControl.MouseButtons.Right;
                    break;
                default:
                    break;
            }
            SharpMedia.MouseDown(new PointS(e.X, e.Y), button);
        }
        public static string MDXDownloadSite = "http://www.microsoft.com/downloads/details.aspx?familyid=2da43d38-db71-4c1b-bc6a-9b6652cd92a3";
        public static void CheckForManagedDirectX()
        {
            try
            {
                // Attempt to load Managed DirectX
                Assembly.Load("Microsoft.DirectX, Version=1.0.2902.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
            }
            catch
            {
                if (MessageBox.Show("Managed DirectX not found, download it now?", "Install MDX", MessageBoxButtons.YesNo, MessageBoxIcon.Stop) == DialogResult.Yes)
                {
                    Process.Start(new ProcessStartInfo()
                    {
                        UseShellExecute = true,
                        FileName = MDXDownloadSite
                    });
                }
                System.Environment.Exit(1);


            }
        }
    }
}
